package com.ts.hidden.fragment.video;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Fragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Loader;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;

import com.ts.hidden.MsConst;
import com.ts.hidden.R;
import com.ts.hidden.dto.DataDbDto;
import com.ts.hidden.service.ServiceMedia;
import com.ts.hidden.service.ServiceMedia.LocalBinder;
import com.ts.tube.utils.ConvertUtils;
import com.ts.tube.utils.FilterLog;

public class VideoFragment extends Fragment implements LoaderCallbacks<Cursor>, SurfaceTextureListener, OnClickListener {

    private static final String TAG = "VideoFragment";
    FilterLog log = new FilterLog(TAG);
    private Context context;

    // layout
    private TextureView textureView;
    private Surface surface;
    private TextView txtName, txtArtist, txtSize, txtCurrent, txtDuration, txtNextSong;

    // controller
    private MediaPlayer player;
    private AudioManager audioManager;
    private ServiceMedia serviceMedia;
    private boolean isBound = false;

    // data
    private List<DataDbDto> listVideos = new ArrayList<DataDbDto>();
    private List<DataDbDto> listFolder = new ArrayList<DataDbDto>();
    private List<DataDbDto> listFile = new ArrayList<DataDbDto>();
    private int currentFile = 0;

    private boolean isInitData = false;
    private boolean isInitSurface = false;

    public static VideoFragment newInstance(String s) {
        VideoFragment f = new VideoFragment();
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.video_fragment, container, false);
        initData();
        initLayout(rootView);
        initListener();
        return rootView;
    }

    private void initData() {
        context = getActivity();
        listVideos.clear();
        listFolder.clear();
        listFile.clear();
        getLoaderManager().initLoader(0, null, this);

        audioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
        IntentFilter filter = new IntentFilter("android.media.VOLUME_CHANGED_ACTION");
        getActivity().registerReceiver(eventReceiver, filter);

        context.bindService(ServiceMedia.getIntentService(context), connection, Service.BIND_AUTO_CREATE);
    }

    private void initLayout(View rootView) {
        textureView = (TextureView) rootView.findViewById(R.id.video_textureview);

        txtName = (TextView) rootView.findViewWithTag("name");
        txtArtist = (TextView) rootView.findViewWithTag("artist");
        txtSize = (TextView) rootView.findViewWithTag("size");
        txtCurrent = (TextView) rootView.findViewWithTag("current");
        txtDuration = (TextView) rootView.findViewWithTag("duration");
        txtNextSong = (TextView) rootView.findViewWithTag("next_song");
    }

    private void initListener() {
        textureView.setSurfaceTextureListener(this);
        textureView.setOnClickListener(this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {

        Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        CursorLoader cursorLoader = new CursorLoader(context, uri, null, null, null, null);
        return cursorLoader;

    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        if (cursor != null && cursor.moveToFirst()) {
            listVideos.clear();
            log.d("log>>>" + "size videos:" + cursor.getCount());
            // StringBuilder builder = new StringBuilder();
            // String[]columns = cursor.getColumnNames();
            // builder = new StringBuilder();
            // for (String string : columns) {
            // builder.append(string);
            // builder.append(":");
            // builder.append(cursor.getString(cursor.getColumnIndex(string)));
            // builder.append(";");
            // }
            // log.d("log>>>" + builder.toString());
            do {
                String _id = cursor.getString(cursor.getColumnIndex("_id"));
                String path = cursor.getString(cursor.getColumnIndex("_data"));
                int type = MsConst.VIDEO;
                String name = cursor.getString(cursor.getColumnIndex("title"));
                String folder = new File(path).getParent() + File.separator;
                String artist = cursor.getString(cursor.getColumnIndex("artist"));
                long length = cursor.getLong(cursor.getColumnIndex("_size"));
                length = length / (1024 * 1024);
                String size = "Size " + length + "MB";
                int iduration = cursor.getInt(cursor.getColumnIndex("duration"));
                String duration = ConvertUtils.milliSecondsToTimer(iduration);
                String resolution = cursor.getString(cursor.getColumnIndex("resolution"));
                DataDbDto dto = new DataDbDto(_id, path, type, name, folder, artist, size, duration, resolution);
                listVideos.add(dto);
            } while (cursor.moveToNext());
        }
        isInitData = true;
        if (isBound && isInitSurface) {
            setUp();
        }

    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {

    }

    @Override
    public void onClick(View v) {

    }

    // TODO surfaceTexture
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface_, int width, int height) {
        log.d("log>>>" + "onSurfaceTextureAvailable");
        isInitSurface = true;
        surface = new Surface(surface_);
        
        if(player != null) {
            player.setSurface(surface);
            return;
        }
        
        if (isInitData && isBound) {
            setUp();
        }

        // displayFileName();
        //
        // if (player != null && player.isPlaying()) {
        // player.stop();
        // player.release();
        // player = null;
        // }
        //
        // resetVideo();
        // textureView.setOpaque(false);
        // playVideo();

    }

    private void resetVideo() {
        try {

            if (listVideos.size() == 0) {
                return;
            }

            if (player == null) {
                initPlayer();
            } else {
                player.reset();
                player.setDataSource(listVideos.get(currentFile).path);
                player.setSurface(surface);
                player.prepare();
            }
            player.start();
            player.seekTo(0);
            Thread.sleep(100);
            player.pause();
        } catch (Exception e) {
            log.e("log>>>" + "resetVideo:" + e.toString());
        }

    }

    private void initPlayer() {

        if (listVideos == null || listVideos.isEmpty()) {
            Log.e("", ">>> listVideos have nothing");
            return;
        }
        player = MediaPlayer.create(getActivity(), Uri.parse(listVideos.get(currentFile).path));
        player.setSurface(surface);
        player.setOnCompletionListener(new OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                playNextVideo();
                playVideo();
            }
        });

        player.setOnErrorListener(new OnErrorListener() {

            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                playNextVideo();
                playVideo();
                return false;
            }
        });

    }

    private void playVideo() {
        if (player == null || listVideos.isEmpty()) {
            return;
        }

        player.start();
    }

    private void playNextVideo() {
        if (listVideos.isEmpty()) {
            return;
        }
        currentFile++;
        if (currentFile == listVideos.size()) {
            currentFile = 0;
        }
        displayFileName();
        resetVideo();

    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        log.d("log>>>" + "onSurfaceTextureDestroyed");
        this.surface = null;
        if(player != null) {
            player.setSurface(null);
        }
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    BroadcastReceiver eventReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context arg0, Intent arg1) {
            log.d("log>>>" + "eventReceiver:" + audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

        }

    };

    @Override
    public void onDestroy() {
        log.i("log>>>" + "VIDEO F onDestroy");
        getActivity().unregisterReceiver(eventReceiver);
//        if (player != null && player.isPlaying()) {
//            player.stop();
//            player.release();
//            player = null;
//        }

        if (serviceMedia != null) {
            context.unbindService(connection);
        }
        super.onDestroy();
    }

    private void displayFileName() {
        if (listVideos.isEmpty()) {
            return;
        }
        DataDbDto dto = listVideos.get(currentFile);
        txtName.setText(dto.name);
        txtSize.setText(dto.size);
        txtDuration.setText(dto.duration);
        txtArtist.setText(dto.artist);
        if (listVideos.size() - 1 > currentFile) {
            txtNextSong.setText("Next: " + listVideos.get(currentFile + 1).name);
        }
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            LocalBinder localBinder = (LocalBinder) service;
            serviceMedia = localBinder.getService();
            isBound = true;
            log.d("log>>>" + "onServiceConnected");
            if (isInitData && isInitSurface) {
                setUp();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            log.d("log>>>" + "onServiceDisconnected");
            serviceMedia = null;
            isBound = false;
        }

    };

    private void setUp() {
        isBound = false;
        isInitData = false;
        isInitSurface = false;
        log.d("log>>>" + "setUp");
        displayFileName();
        player = serviceMedia.getPlayer();
        if (listVideos.size() == 0) {
            return;
        }
        resetVideo2();
//        serviceMedia.playVideo();
//        player.start();
    }

    private void resetVideo2() {
        try {

            if (listVideos.size() == 0) {
                return;
            }
            
            if(player.isPlaying()) {
                Thread.sleep(100);
                player.setSurface(surface);
                return;
            }

            player.reset();
            player.setDataSource(listVideos.get(currentFile).path);
            player.setSurface(surface);
            player.prepare();

            player.start();
            player.seekTo(0);
            Thread.sleep(100);
//            player.pause();
        } catch (Exception e) {
            log.e("log>>>" + "resetVideo:" + e.toString());
        }

    }
}
